A few new features have been added to the Threads package since it appeared in issue 7 of Develop. The main enhancement is the ability to create an application that uses the Threads and Futures package, but does not depend on the Threads INIT.
The new version of the Threads package will attempt to load the Threads INIT if it was not present in the System folder when the machine started up. Use ResEdit to copy 'INIT' resource 1 and 'CODE' resource 30217 from the Threads INIT, and paste them into the resource fork of your application. If the Threads INIT has not been loaded when your application calls InitThreads, the threads package will be loaded into the system heap automatically.
pascal OSErr InitThreads( short threadFlags )
The call to InitThreads is more or less the same as it was presented in Develop 7; it is still possible to pass 'true' or 'false' to InitThreads, and doing so will cause the threads package to behave the same way it was documented in that issue. There are other values that may be provided, though:
kUsesFPU
kMainThreadHasPriority
kDreamEveryTick
kUsesFPU specifies whether or not the threads package should save the floating point registers on context switches.
Specifying kMainThreadHasPriority will cause the threads package to swap in the main thread whenever events are pending, even if there are other threads that have not had a chance to run.
The flag kDreamEveryTick, if specified, will cause the threads package to call the 'LetThreadsDream' procedure periodically. Threads are given time to dream when Yield is called if they have not dreamed within the last tick (1/60th of a second). If the kDreamEveryTick flag is not specified, threads will not dream unless your application explicitly calls 'LetThreadsDream'.
SleepForNTicks puts the thread to sleep, but it also installs a dream procedure that will wake the thread up once the specified sleep time has elapsed. If your application has installed a dreaming procedure, it will also be called while the thread sleeps.
RegisterContextGlobal installs a special custom swapping routine that saves and restores the specified long integer (or pointer) every time a thread swaps in or swaps out. Most custom swapping procedures didn't do anything other than swap a few pointers, so RegisterContextGlobal was provided to greatly simplify applications in this situation. Any number of globals may be registered with this routine; none of the thread's fUserBytes are used to save or restore the globals registered.
RegisterContextGlobal must be called at the beginning of your application, before any new threads have been started.
pascal Boolean InMainThread()
InMainThread returns 'true' if the current thread is the main thread.
pascal ThreadHandle GetMainThread()
GetMainThread returns the ThreadHandle of the main thread.
pascal ThreadProc InstallSwapProc( long selector,
ThreadProc newSwap )
InstallSwapProc installs a customized swapping procedure, and returns a function pointer to the old swapping routine. It is still permissible to set up custom swapping procedures as described in Develop issue 7.
The valid selectors for InstallSwapProc are:
kCopyContextSel
kSwapInSel
kSwapOutSel
kFreeThreadSel
kScheduleSel
kPreYieldSel
kPostYieldSel
The selectors kCopyContextSel, kSwapInSel, kSwapOutSel, kFreeThreadSel and kScheduleSel are described in Develop issue 7. kPreYieldSel specifies a routine that is called at the beginning of every Yield() instruction, and kPostYieldSel is called at the end of every Yield(). It is not likely that you will need to install a pre-yield or post-yield swapping procedure; usually, you should override CopyContext and SwapIn.
Note: the schedule procedure is actually a SceduleProc, not a ThreadProc. The prototypes for these function pointers are: